# -*- encoding: utf-8 -*-

"""
googlemapspython - Google Maps class for Python 
Copyright (c) 2009 Josep Maria Brunetti


License:

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
"""

import re

class Icon(object):
    """Class that represents Google Maps Icons"""
    def __init__(self,img,shadow=None):
        self.img = img
        self.shadow = shadow
        
    
class Point(object):
    """Class that represents Google Maps Markers"""
    def __init__(self, lat, lon, html=None, icon=None):
        self.lat = float(lat);
        self.lon = float(lon);
        self.html = html;
        self.icon = icon
        

class Map(object):
    """Class that represents Google Maps objects"""
    def __init__(self, key, id):
        self.key = key
        self.id = id
        self.points = []
        self.centerLat = 0.0
        self.centerLon = 0.0
        self.zoom = None
        
        
    def __getBounds(self):
        minLat = min(p.lat for p in self.points) if self.points else 0
        minLon = min(p.lon for p in self.points) if self.points else 0
        maxLat = max(p.lat for p in self.points) if self.points else 0
        maxLon = max(p.lon for p in self.points) if self.points else 0
        return Point(minLat, minLon), Point(maxLat,maxLon)
        
        
    def setCenter(self, lat, lon):
        """Method to set map's center"""
        self.centerLat = lat
        self.centerLon = lon
        
    
    def setZoom(self, zoom):
        """Method to set map's zoom"""
        self.zoom = zoom
        
        
    def addPoint(self, point):
        """Method that adds a marker"""
        self.points.append(point) 
    
    
    def __printKey(self):
        output = """
            <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;sensor=false&amp;key=%s"
            type="text/javascript"></script>
            """ % self.key
        return output
    
    
    def __printCenter(self):
        if self.points:
            leftBound, rightBound = self.__getBounds()
            output = """
                var minLat = %s;
                var minLon = %s;
                var maxLat = %s;
                var maxLon = %s;
                botLeft = new GLatLng(minLat, minLon);
                topRight = new GLatLng(maxLat, maxLon);
                bounds = new GLatLngBounds(botLeft, topRight);
                """ % (leftBound.lat, leftBound.lon, rightBound.lat, rightBound.lon)
            if self.zoom:
                output += "map.setCenter(new GLatLng((maxLat + minLat)/2,(maxLon + minLon)/2),%s);" % self.zoom
            else:
                output += "map.setCenter(new GLatLng((maxLat + minLat)/2,(maxLon + minLon)/2),map.getBoundsZoomLevel(bounds));"
        else:
            output = 'map.setCenter(new GLatLng(40,-20),1);'
        return output
    
    
    def __printIcons(self):
        output = ['var icons = [];']
        for i,point in enumerate(self.points):
            if point.icon:
                output.append('icons[%s] = new GIcon();' % i)
                output.append('icons[%s].image = "%s";' % (i,point.icon.img))
                if point.icon.shadow:
                    output.append('icons[%s].shadow = "%s";' % (i,point.icon.shadow))
                output.append('icons[%s].shadowSize = new GSize(33,34);' % i)
                output.append('icons[%s].iconAnchor = new GPoint(15,26);' % i)
                output.append('icons[%s].infoWindowAnchor = new GPoint(20,20);' % i)
        return ''.join(output)
                
    
    def __printPoints(self):
        output = []
        for i,point in enumerate(self.points):
            output.append("""
                point = new GLatLng(%s,%s)
                map.addOverlay(createMarker(point, [new GInfoWindowTab('test','%s')],%s));
              """ % (point.lat, point.lon, re.escape(point.html), i))
        return ''.join(output)
    
    
    def printMap(self):
        """Method that prints javascript code for the map"""
        output = self.__printKey()
        output += """
            <script type="text/javascript">    
            function loadMap(){
                if (GBrowserIsCompatible()) {
                    var map = new GMap2(document.getElementById("%s"));
                    map.addControl(new GSmallMapControl());
                    map.addControl(new GMapTypeControl());
                    %s
                    function createMarker(point,html,n) {
                        var marker = new GMarker(point,icons[n]);
                        GEvent.addListener(marker, "click", function() {
                        marker.openInfoWindowTabsHtml(html);
                    });
                    return marker;
                    }
                    %s
                    %s
                }
            }
            
            window.onload = loadMap;
            </script> 
            """ % (self.id, self.__printCenter(), self.__printIcons(), self.__printPoints())
        return output